<!doctype html>
<html>
<head>
    <script src="../../../build/output/playcanvas-latest.js"></script>
    <script src="http://code.playcanvas.com/ammo.751ec5f.js"></script>
    <link href="../../style.css" rel="stylesheet" />
</head>

<body>
    <!-- The canvas element -->
    <canvas id="application-canvas"></canvas>

    <!-- The script -->
    <script>
    // ***********    Initialize application   *******************
    var canvas = document.getElementById("application-canvas");

    // Create the application and start the update loop
    var app = new pc.Application(canvas);
    app.start();

    // Set the canvas to fill the window and automatically change resolution to be the same as the canvas size
    app.setCanvasFillMode(pc.FILLMODE_FILL_WINDOW);
    app.setCanvasResolution(pc.RESOLUTION_AUTO);

    app.scene.ambientLight = new pc.Color(0.2, 0.2, 0.2);

    // Set the gravity for our rigid bodies
    app.systems.rigidbody.setGravity(0, -9.8, 0);

    function createMaterial (color) {
        var material = new pc.PhongMaterial();
        material.diffuse = color;
        // we need to call material.update when we change its properties
        material.update()
        return material;
    }

    // create a few materials for our objects
    var white = createMaterial(new pc.Color(1, 1, 1));
    var red = createMaterial(new pc.Color(1, 0, 0));
    var green = createMaterial(new pc.Color(0, 1, 0));
    var blue = createMaterial(new pc.Color(0, 0, 1));
    var yellow = createMaterial(new pc.Color(1, 1, 0));

    // ***********    Create our floor   *******************

    var floor = new pc.Entity();
    floor.addComponent("model", {
        type: "box"
    });

    // make the floor white
    floor.model.material = white;

    // scale it
    floor.setLocalScale(10, 1, 10);

    // add a rigidbody component so that other objects collide with it
    floor.addComponent("rigidbody", {
        type: "static",
        restitution: 0.5
    });

    // add a collision component
    floor.addComponent("collision", {
        type: "box",
        halfExtents: new pc.Vec3(5, 0.5, 5)
    });

    // add the floor to the hierarchy
    app.root.addChild(floor);

    // ***********    Create lights   *******************

    // make our scene prettier by adding a directional light
    var light = new pc.Entity();
    light.addComponent("light", {
        type: "directional",
        color: new pc.Color(1, 1, 1),
        castShadows: true,
        shadowBias: 0.05,
        normalOffsetBias: 0.05,
        shadowResolution: 2048
    });

    // set the direction for our light
    light.setLocalEulerAngles(45, 30, 0);

    // Add the light to the hierarchy
    app.root.addChild(light);

    // ***********    Create camera    *******************

    // Create an Entity with a camera component
    var camera = new pc.Entity();
    camera.addComponent("camera", {
        clearColor: new pc.Color(0.5, 0.5, 0.8),
        farClip: 50
    });

    // add the camera to the hierarchy
    app.root.addChild(camera);

    // Move the camera a little further away
    camera.translate(0, 10, 15);
    camera.lookAt(0, 0, 0);

    // ***********    Create templates    *******************

    // Create a template for a falling box
    // It will have a model component of type 'box'...
    var boxTemplate = new pc.Entity();
    boxTemplate.addComponent("model", {
        type: "box",
        castShadows: true
    });

     // ...a rigidbody component of type 'dynamic' so that it is simulated
    // by the physics engine...
    boxTemplate.addComponent("rigidbody", {
        type: "dynamic",
        mass: 50,
        restitution: 0.5
    });

    // ... and a collision component of type 'box'
    boxTemplate.addComponent("collision", {
        type: "box",
        halfExtents: new pc.Vec3(0.5, 0.5, 0.5)
    });

    // make the box red
    boxTemplate.model.material = red;

    // Create other shapes too for variety...

    // A sphere...
    var sphereTemplate = new pc.Entity();
    sphereTemplate.addComponent("model", {
        type: "sphere",
        castShadows: true
    });

    sphereTemplate.addComponent("rigidbody", {
        type: "dynamic",
        mass: 50,
        restitution: 0.5
    });

    sphereTemplate.addComponent("collision", {
        type: "sphere",
        radius: 0.5
    });


    // make the sphere green
    sphereTemplate.model.material = green;

    // A capsule...
    var capsuleTemplate = new pc.Entity();
    capsuleTemplate.addComponent("model", {
        type: "capsule",
        castShadows: true
    });

    capsuleTemplate.addComponent("rigidbody", {
        type: "dynamic",
        mass: 50,
        restitution: 0.5
    });

    capsuleTemplate.addComponent("collision", {
        type: "capsule",
        radius: 0.5,
        height: 2
    });


    // make the capsule blue
    capsuleTemplate.model.material = blue;

    // A cylinder...
    var cylinderTemplate = new pc.Entity();
    cylinderTemplate.addComponent("model", {
        type: "cylinder",
        castShadows: true
    });

    cylinderTemplate.addComponent("rigidbody", {
        type: "dynamic",
        mass: 50,
        restitution: 0.5
    });

    cylinderTemplate.addComponent("collision", {
        type: "cylinder",
        radius: 0.5,
        height: 1
    });


    // make the cylinder yellow
    cylinderTemplate.model.material = yellow;

    // add all the templates to an array so that
    // we can randomly spawn them
    var templates = [boxTemplate, sphereTemplate, capsuleTemplate, cylinderTemplate];

    // disable the templates because we don't want them to be visible
    // we'll just use them to clone other Entities
    templates.forEach(function (template) {
        template.enabled = false;
    })

    // ***********    Update Function   *******************

    // initialize variables for our update function
    var timer = 0;
    var count = 40;

    // Set an update function on the application's update event
    app.on("update", function (dt) {
        // create a falling box every 0.2 seconds
        if (count > 0) {
            timer -= dt;
            if (timer <= 0) {
                count--;
                timer = 0.2;

                // Clone a random template and position it above the floor
                var template = templates[Math.floor(pc.math.random(0, templates.length))];
                var clone = template.clone();
                // enable the clone because the template is disabled
                clone.enabled = true;

                app.root.addChild(clone);

                clone.rigidbody.teleport(pc.math.random(-1, 1), 10, pc.math.random(-1, 1));
            }
        }

    });

    </script>
</body>
</html>
